package com.starview.star.operators.io.runtime;

import com.starview.platform.data.EvaluationException;
import com.starview.platform.data.IFunction;
import com.starview.platform.data.IValue;
import com.starview.platform.data.type.IType;
import com.starview.platform.data.type.StandardTypes;
import com.starview.platform.data.type.TypeUtils;
import com.starview.platform.data.value.Factory;
import com.starview.star.operators.CafeEnter;
import com.starview.star.operators.io.runtime.IOHandle.ReaderHandle;
import com.starview.star.operators.io.runtime.IOHandle.SocketHandle;
import com.starview.star.operators.io.runtime.IOHandle.WriterHandle;

public class OpenIO
{
  public static class Connect implements IFunction
  {
    public static final String name = "__connect";

    @CafeEnter
    public static IOHandle enter(String host, int port) throws EvaluationException
    {
      return new SocketHandle(host, port);
    }

    @Override
    public IValue enter(IValue... args) throws EvaluationException
    {
      return enter(Factory.stringValue(args[0]), Factory.intValue(args[1]));
    }

    @Override
    public IType getType()
    {
      return type();
    }

    public static IType type()
    {
      return TypeUtils.functionType(new IType[] { StandardTypes.rawStringType, StandardTypes.rawIntegerType },
          IOHandle.type);
    }
  }

  public static class OpenInfile implements IFunction
  {
    public static final String name = "__openInFile";

    @CafeEnter
    public static IOHandle enter(String fileName) throws EvaluationException
    {
      return new ReaderHandle(fileName);
    }

    @Override
    public IValue enter(IValue... args) throws EvaluationException
    {
      return enter(Factory.stringValue(args[0]));
    }

    @Override
    public IType getType()
    {
      return type();
    }

    public static IType type()
    {
      return TypeUtils.functionType(StandardTypes.rawStringType, IOHandle.type);
    }
  }

  public static class OpenOutfile implements IFunction
  {
    public static final String name = "__openOutFile";

    @CafeEnter
    public static IOHandle enter(String fileName) throws EvaluationException
    {
      return new WriterHandle(fileName);
    }

    @Override
    public IValue enter(IValue... args) throws EvaluationException
    {
      return enter(Factory.stringValue(args[0]));
    }

    @Override
    public IType getType()
    {
      return type();
    }

    public static IType type()
    {
      return TypeUtils.functionType(StandardTypes.rawStringType, IOHandle.type);
    }
  }

  public static class CloseFile implements IFunction
  {
    public static final String name = "__closeIO";

    @CafeEnter
    public static IValue enter(IOHandle handle) throws EvaluationException
    {
      handle.close();
      return StandardTypes.unit;
    }

    @Override
    public IValue enter(IValue... args) throws EvaluationException
    {
      return enter((IOHandle) args[0]);
    }

    @Override
    public IType getType()
    {
      return type();
    }

    public static IType type()
    {
      return TypeUtils.procedureType(IOHandle.type);
    }
  }
}
